﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using CoolCode.Linq.Expressions;

namespace CoolCode.SpeedTests
{
    class Program
    {
        static void Main(string[] args)
        {
            //Test3();
            Test4();
            Console.Read();
        }

        static void Test4()
        {
            Console.WriteLine("CreateInstance(带多参数): ");

            Stopwatch watcher = new Stopwatch();
            int count = 100000;
            Type type = typeof(Bar);

            watcher.Reset();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                Activator.CreateInstance(type, i, "string");
            }
            watcher.Stop();
            Console.WriteLine("Activator: " + watcher.Elapsed);

            watcher.Reset();
            watcher.Start();
            var createInstance = type.CreateInstanceDelegate( 1,"" );
            for (int i = 0; i < count; i++)
            {
                createInstance.DynamicInvoke(i, "string");
            }
            watcher.Stop();
            Console.WriteLine("Expression: " + watcher.Elapsed);

            watcher.Reset();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                new Bar(i, "string");
            }
            watcher.Stop();
            Console.WriteLine("Direct: " + watcher.Elapsed);
        }

        static void Test3()
        {
            Console.WriteLine("CreateInstance(带多参数): ");

            Stopwatch watcher = new Stopwatch();
            int count = 100000;
            Type type = typeof(Bar);

            watcher.Reset();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                Activator.CreateInstance(type, i, "string");
            }
            watcher.Stop();
            Console.WriteLine("Activator: " + watcher.Elapsed);

            watcher.Reset();
            watcher.Start();
            var createInstance = type.CreateInstanceDelegate<int,string>();
            for (int i = 0; i < count; i++)
            {
                createInstance(i,"string");
            }
            watcher.Stop();
            Console.WriteLine("Expression: " + watcher.Elapsed);

            watcher.Reset();
            watcher.Start(); 
            for (int i = 0; i < count; i++)
            {
               new Bar(i, "string");
            }
            watcher.Stop();
            Console.WriteLine("Direct: " + watcher.Elapsed);
        }

        static void Test2()
        {
            Console.WriteLine("CreateInstance(带1参数): ");

            Stopwatch watcher= new Stopwatch();
            int count = 100000;
            Type type = typeof(Bar); 
 
            watcher.Reset();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {  
                Activator.CreateInstance(type,i); 
            }
            watcher.Stop();
            Console.WriteLine("Activator: " + watcher.Elapsed);

            watcher.Reset();
            watcher.Start();
            var createInstance = type.CreateInstanceDelegate<int>();
            for (int i = 0; i < count; i++)
            { 
                createInstance(i); 
            }
            watcher.Stop();
            Console.WriteLine("Expression: " + watcher.Elapsed);

        }

        static void Test1()
        {
            Stopwatch watcher;
            int count = 1000000;
            Type type = typeof(Foo);
            Type[] types = new Type[]{ typeof(Foo1),
                typeof(Foo2) ,typeof(Foo3) ,typeof(Foo4) ,typeof(Foo5) };

            watcher = new Stopwatch();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                //object obj = Activator.CreateInstance(type);
                types.ForEach(t => Activator.CreateInstance(t));
            }
            watcher.Stop();
            Console.WriteLine("Activator: " + watcher.Elapsed);

            watcher = new Stopwatch();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                //object obj = type.CreateInstance();
                types.ForEach(t => t.CreateInstance());
            }
            watcher.Stop();
            Console.WriteLine("Expression: " + watcher.Elapsed);

            watcher = new Stopwatch();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                Activator.CreateInstance(type);
            }
            watcher.Stop();
            Console.WriteLine("Activator2: " + watcher.Elapsed);

            watcher = new Stopwatch();
            watcher.Start();
            for (int i = 0; i < count; i++)
            {
                type.CreateInstance();
            }
            watcher.Stop();
            Console.WriteLine("Expression2: " + watcher.Elapsed);
        }
    }

    public class Bar
    { 
        public Bar(int num)
        { 
        }

        public Bar(int num, string str)
        { 
        }

        //public override string ToString()
        //{
        //    return "num:"+_num ;
        //}
    }

    public class Foo { }
    public class Foo1 { }
    public class Foo2 { }
    public class Foo3 { }
    public class Foo4 { }
    public class Foo5 { }
}
